package com.store.controller.lt;

import com.aliyuncs.http.HttpRequest;
import com.store.entity.Resource;
import com.store.entity.Role;
import com.store.entity.User;
import com.store.service.lt.UserService;
import com.store.utils.RequestUtils;
import com.store.utils.SendPhoneCodeUtil;
import com.store.utils.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.ws.spi.http.HttpContext;
import java.io.IOException;
import java.util.*;


@Controller
@RequestMapping(value = "/lt_auth", name = "登陆控制器")
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private RequestUtils requestUtils;

    @RequestMapping(value = "/lt_login", method = RequestMethod.POST, name = "POST登陆")
    public String submitLogin(String username, String password, HttpServletRequest request) {
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            String pwd = new String((char[]) token.getCredentials());
            // System.out.println("前端获取的密码："+ pwd);
            // System.out.println("前端账号："+token.getUsername()+"密码："+pwd);
            //获取当前用户的所有信息，包装Subject对象中
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isAuthenticated()) {
                subject.login(token);
                //没有操作的情况下，多少毫秒之后T出登陆
                //shiro会默认拿这个数除以1000.默认去掉小数。
                //不能设置为0
                //永久有效，设置为-1000以上都行
                //设置再登陆之后
                //默认是30分钟1800000毫秒
                subject.getSession().setTimeout(1000000);//毫秒为单位
                User user = (User) subject.getPrincipal();
                request.setAttribute("user",user);
                //记住密码
                token.setRememberMe(true);
            }

        } catch (DisabledAccountException e) {
            request.getSession().setAttribute("msg", "账户已被禁用");
            System.out.println("账户已被禁用");
            return "redirect:lt_toLogin";
        } catch (AuthenticationException e) {
            request.getSession().setAttribute("msg", "用户名或密码错误");
            System.out.println("用户名或密码错误");
            return "redirect:lt_toLogin";
        }
        // 执行到这里说明用户已登录成功
        return "Reception/index";
    }

    //登出
    @RequestMapping(value = "/lt_logout")
    public String logout() {
            Subject subject = SecurityUtils.getSubject();
            subject.logout();//清空当前subject对象
        return "redirect:lt_toLogin";
    }

    @RequestMapping(value = "/lt_toRegister")
    public String Register() {
        return "Reception/register";
    }

    @RequestMapping(value = "/lt_toLogin"/*, method = RequestMethod.POST, name = "GET登陆页面"*/)
    public String loginPage() {
        return "Reception/login";
    }

    @RequestMapping(value = "/lt_toIndex", method = RequestMethod.GET, name = "GET首页面")
    public String indexPage() {
        return "Reception/index";
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET, name = "后台首页")
    public String loginSuccessMessage(HttpServletRequest request) {
        String username = "未登录";
        //获取当前的用户
        User currentLoginUser = RequestUtils.currentLoginUser();

        if (currentLoginUser != null && StringUtils.isNotEmpty(currentLoginUser.getUsername())) {
            username = currentLoginUser.getUsername();
        } else {
            return "redirect:/auth/toLogin";
        }
        //查询所有用户
        List<User> users = userService.queryUsers();
        //查询每个用户对应的所有角色
        //告诉TreeMap按照对象中的某个字段进行排序
        Map<User, List<Role>> map = new TreeMap<>(
                Comparator.comparing(User::getId));
        //遍历所有的用户
        for (User user : users) {
            //根据用户id查询所有的角色
            List<Role> roles = userService.queryRolesByUser(user);
            map.put(user, roles);
        }

        //查询所有存在的角色
        List<Role> roles = userService.queryRoles();
        request.setAttribute("username", username);
        request.setAttribute("map", map);
        request.setAttribute("roles", roles);
        return "index";
    }

    //被踢出后跳转的页面
    @RequestMapping(value = "/kickout", method = RequestMethod.GET, name = "登陆限制")
    public String kickOut() {
        return "kickout";
    }

    //@RequiresPermissions(value = {"auth:updateAuthority"})
    @RequestMapping(value = "/updateAuthority", name = "更新权限")
    public String updateAuthority(Model model) throws IOException, ClassNotFoundException {

        //获取控制层下所有的访问路径
        List<Resource> resources = requestUtils.getResources();

        //数据库查询的所有资源权限数据
        List<Resource> resourcesAll = userService.queryResources();

        List<Resource> resourcesAdd = new ArrayList<>();
        //查找没有增加进去的资源权限
        for (Resource resource : resources) {
            boolean flag = false;
            //一个一个去比较
            for (Resource sysResources : resourcesAll) {
                if (resource.getResurl().equals(sysResources.getResurl())) {
                    flag = true;//已存在，不加入
                    break;
                }
            }
            if (!flag) {
                //没有进入if条件，证明不存在
                resourcesAdd.add(resource);
            }
        }
        //将需要增加的权限加入到数据库
        int count = userService.addResources(resourcesAdd);

        //又查询一次所有的资源权限
        //将新加入的权限与之前查询的权限整合到一起
        resourcesAll.addAll(resourcesAdd);
        model.addAttribute("resources", resourcesAll);
        model.addAttribute("count", count);
        return "synchroAuthority";
    }

    @RequiresRoles(value = {"admin"})
    @RequestMapping(value = "/queryAllAuthority", name = "分配所有的权限")
    public String queryAllAuthority(Model model, Role role) {
        //查询所有的资源权限
        List<Resource> resources = userService.queryResources();
        //查询所有的角色
        List<Role> roles = userService.queryRoles();
        //根据前端传递角色的id查询对应的权限
        List<Resource> resourcesRoles = userService.queryResourcesByRoleId(role.getId());
        //匹配每一个是否有权限
        Map<Resource, Object> map = new TreeMap<>(
                Comparator.comparing(Resource::getResurl));
        for (Resource resource : resources) {
            boolean flag = false;
            for (Resource resourcesRole : resourcesRoles) {
                if (resource.getResurl().equals(resourcesRole.getResurl())) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                map.put(resource, 1);
            } else {
                map.put(resource, 0);
            }
        }

        model.addAttribute("roles", roles);
        model.addAttribute("currRole", role);
        model.addAttribute("resourcesMap", map);
        return "assignPermissions";
    }

    @RequestMapping(value = "/toReg", name = "去注册页面")
    public String toReg(){
        return "reg";
    }

    @RequestMapping(value = "/lt_reg", name = "注册")
    public String reg(HttpServletRequest request){
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String phone = request.getParameter("phone");
        System.out.println("username："+username +"password："+password);
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setPhone(phone);
        user.setStatus("1");//默认锁定
        //加密类型
        String hashAlgorithmName = "SHA1";
        //需要加密的密码
        Object credentials = user.getPassword();
        //随机生成的盐值
        String saltStr = UUID.randomUUID().toString().replaceAll("\\-","");
        //用户名作为盐值，用户名是唯一，配上密码就是唯一的。
        Object salt = ByteSource.Util.bytes(saltStr);
        //Object salt = null;
        int hashIterations = 256;
        //生成一个新的密码
        Object newPwd = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
        //设置新密码到用户中
        user.setPassword(newPwd.toString());
        user.setSalt(saltStr);
        //新增
        System.out.println("测试："+user.toString());
        boolean result = userService.addUser(user);
        return "Reception/login";
    }


    @RequestMapping(value = "/addAuthority", name = "增加权限")
    public String addAuthority(Integer roleId, Integer resourcesId, Integer has, String rolename){
        if (has == 1) {
            //需要增加权限
            boolean b = userService.addAuthority(roleId, resourcesId);
        } else {
            //需要删除权限
            boolean b = userService.deleteAuthority(roleId, resourcesId);
        }
        return "redirect:/auth/queryAllAuthority?id="+resourcesId+"&rolename="+rolename;
    }


    @RequestMapping(value = "/lock", name = "解锁和锁定")
    public String lock(Integer userId, String status){
        boolean result = userService.updateUserByLock(userId, status);
        return "redirect:/auth/index";
    }

    @RequestMapping(value = "/giveRole", name = "赋予用户角色")
    public String giveRole(Integer userId, Integer roleId, boolean checked) {
        if (checked) {
            //为true代表被选中
            boolean result = userService.addUserRole(userId, roleId);
        } else {
            //否则去除权限
            boolean result = userService.deleteUserRole(userId, roleId);
        }

        return "redirect:/auth/index";
    }


    @RequestMapping(value = "/addRole", name = "增加权限")
    public String toIndex(Role role){
        boolean b = userService.addRole(role);
        return "redirect:/auth/queryAllAuthority";
    }

    /**
     * 获取验证码
     */
    @RequestMapping(value = "/sendCode")
    @ResponseBody
    private void sendCode(Model model, HttpServletResponse response) {
        String phone = (String) model.getAttribute("phone");
        SendPhoneCodeUtil sendPhoneCodeUtil = new SendPhoneCodeUtil(phone);
        sendPhoneCodeUtil.send();
        String code = sendPhoneCodeUtil.getCode();
        WebUtils.sendMSG(response,code);
    }

    /**
     * 验证用户名是否被注册
     */
    @RequestMapping(value = "/checkUsername")
    private String checkUsername(@ModelAttribute("username")String username) {
        User user = userService.queryUserByUsername(username);
        return user == null?"1":"-1";
    }




}
